package cn.edu.nju.ws.sview.rdf;

import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Map.Entry;

import cn.edu.nju.ws.sview.cache.URIIDCache;
import cn.edu.nju.ws.sview.cache.URILabelCache;
import cn.edu.nju.ws.sview.cache.URITypeCache;
import cn.edu.nju.ws.sview.crawler.Crawler;
import cn.edu.nju.ws.sview.crawler.Element;
import cn.edu.nju.ws.sview.database.DBOperations;
import cn.edu.nju.ws.sview.util.URIUtil;

/**
 * URI
 * 
 * @author Gong Saisai
 * @author dhuang
 */
public class URIResource extends Resource {
	protected String uri = null;
	public static String EXPIRED ="expired" ;
	public static String NOT_PINGED = "notpinged";
	public static String VALID = "valid";
	public static String VALID_FAILED = "valid_failed";
	public static String VALID_SUCCEED = "valid_succeed";
	
    /**
     * 
     * @param uri The URI of the resource
     */
	protected URIResource(String uri) {
		this.uri = uri;
	}
	
	public static  int getURIIdByURIString(String uri) {
		int id = -1;
	    try {
			id = URIIDCache.getInstance().getURIID(uri, true) ;
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return id;
	}
	
	public  int getID(){
		return this.getURIIdByURIString(this.uri);
	}

	/**
	 * get the URIResource constructed by the origin uri
	 * @param id
	 * @return
	 */
	public static URIResource getURIResourceById(int id){
		String uri = null;
		try {
			uri = URIIDCache.getInstance().getURI(new Integer(id));
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		URIResource res = ResourceFactory.getInstance().createURIResource(uri);
		return res;
	}
	
	public String getURI() {
		return this.uri;
	}
	
	public boolean isInternalURI(){
		if(this.uri.startsWith(ResourceFactory.INTERNAL_URI_PREFIX))
		   return true;
		else
			return false;
	}
    
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof URIResource){
			URIResource uriResource = (URIResource)obj;
			if(this.uri.equals(uriResource.getURI()))
					return true;
		}
		return false;
	}

	public String toString() {
		return "<" + this.uri + ">";
	}
	
	
	/**
	 * get the types of origin class
	 * @param id origin class id
	 * @return <typeID,typeLabel>
	 */
	public static ArrayList<Entry<Integer, String>> getTypesById(int id,String lang) {
		ArrayList<Entry<Integer, String>> types = new ArrayList<Entry<Integer,String>>();
		HashSet<Integer> typeSet = new HashSet<Integer>();
		try {
			typeSet = URITypeCache.getInstance().getTypes(id) ;
		} catch (Throwable e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		for(Integer ele:typeSet){
			String label = null;
			try {
				label = URILabelCache.getInstance().getLabel(ele, lang);
				if(label.equals("")){
					/*check whether the class uri is dereferenced*/
					if(DBOperations.getValidStatus(ele)==URIResource.NOT_PINGED){
						URIResource uriRes  = ResourceFactory.getInstance().createURIResource(URIIDCache.getInstance().getURI(ele));
						Crawler.getInstance().promoteWeight(uriRes, Element.LEVEL_1) ;
						Crawler.getInstance().submitURI(uriRes);
					}
				}
				label = URILabelCache.getInstance().getLabel(ele, lang);
				if(label.equals(""))
					label = URIUtil.getLocalname(URIIDCache.getInstance().getURI(ele));
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			types.add(new SimpleEntry<Integer, String>(ele, label));
		}
		return types;
	}
	
	/**
	 * 得到uri的label，须检测是否解析过该uri，如果没有首先解析uri。此时如果仍然没有理想的label,
	 * 那么得到它的localname
	 * @param id
	 * @param lang
	 * @return
	 */
	public static String getLabel(int id,String lang) {
		String label = null;
		try {
			String uri = null;
			URIResource r = null;
			try {
				uri = URIIDCache.getInstance().getURI(id);
				r = ResourceFactory.getInstance().createURIResource(uri);
			} catch (Throwable e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			/* check whether the class uri is dereferenced */
			if (DBOperations.getValidStatus(id) != URIResource.VALID
					&& Crawler.getInstance().checkStatus(r) == Crawler.STATUS_UNSUBMITTED) {
				Crawler.getInstance().submitURI(r);
				Crawler.getInstance().promoteWeight(r, Element.LEVEL_1);
			}
			label = URILabelCache.getInstance().getLabel(id, lang);
			if (label.trim().equals("")) {
				label = URIUtil.getLocalname(uri);
			}

		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return label;
	}
}

